package com.hcc.repository.gen.metadata.dialect;

import com.hcc.repository.core.jdbc.ResultMapper;
import com.hcc.repository.core.utils.ReflectUtils;
import com.hcc.repository.gen.metadata.AbstractMetadataQuery;
import com.hcc.repository.gen.model.ColumnMetadata;
import com.hcc.repository.gen.model.TableMetadata;
import com.mysql.cj.MysqlType;

/**
 * Mysql的元数据查询实现
 *
 * @author hushengjun
 * @date 2023/9/28
 */
public class MysqlMetadataQuery extends AbstractMetadataQuery {

    @Override
    protected String queryTableMetadataSql(String tableName) {
        return String.format("SHOW TABLE STATUS WHERE `Name` = '%s'", tableName);
    }

    @Override
    protected String queryColumnMetadataSql(String tableName) {
        return String.format("SHOW FULL FIELDS FROM `%s`", tableName);
    }

    @Override
    protected ResultMapper<TableMetadata> buildTableResultMapper() {
        return (rs, rowNum) -> {
            TableMetadata metadata = new TableMetadata();
            metadata.setName(rs.getString("Name"));
            metadata.setComment(rs.getString("Comment"));

            return metadata;
        };
    }

    @Override
    protected ResultMapper<ColumnMetadata> buildColumnResultMapper() {
        return (rs, rowNum) -> {
            ColumnMetadata metadata = new ColumnMetadata();
            metadata.setName(rs.getString("Field"));
            String type = rs.getString("Type").toLowerCase();
            int indexOf = type.indexOf("(");
            if (indexOf == -1) {
                metadata.setColumnType(type);
            } else {
                metadata.setColumnType(type.substring(0, indexOf));
            }
            metadata.setNullable("YES".equals(rs.getString("Null")));
            metadata.setComment(rs.getString("Comment"));
            metadata.setPrimary("PRI".equals(rs.getString("Key")));
            metadata.setAutoIncrement("auto_increment".equals(rs.getString("Extra")));

            return metadata;
        };
    }

    @Override
    protected Class<?> getJavaType(String jdbcType) {
        MysqlType mysqlType = MysqlType.getByName(jdbcType);
        if (mysqlType == null) {
            return Object.class;
        }
        return ReflectUtils.forName(mysqlType.getClassName());
    }

}
